package com.aconcagua.mvc.control {
  import com.aconcagua.mvc.control.support.CommandExecutorSupport;
  
  import flash.events.Event;
  import flash.events.IEventDispatcher;
  
  public class Controller {
    private var _eventDispatcher: IEventDispatcher;
    private var _commandFactory: CommandFactory;
    private var _mappings: Object;
    private var _commandExecutor: CommandExecutor;

    public function Controller(dispatcher: IEventDispatcher, commandFactory: CommandFactory) {
      _eventDispatcher = dispatcher;
      _commandFactory = commandFactory;
      _mappings = new Object();
      _commandExecutor = new CommandExecutorSupport();
    }

    /**
    * @param array array of GestureMapping
    **/
    public function set mappings(array: Array): void {
      for each (var mapping: GestureMapping in array) {
        var gestureType: String = mapping.gesture;
        
        _mappings[gestureType] = mapping;

        _eventDispatcher.addEventListener(
          gestureType, 
          dispatchGesture
        );
      }
    }

    public function set commandExecutor(executor: CommandExecutor): void {
      _commandExecutor = executor;
    }

    public function dispatchGesture(gesture: Event): void {
      var gestureType: String = gesture.type;
      var mapping: GestureMapping = this.getMappingForGesture(gestureType);
      
      this.executeMapping(gesture, mapping);
    }

    protected function getMappingForGesture(gestureType: String): GestureMapping {
      return _mappings[gestureType];  
    }

    protected function executeMapping(gesture: Event, mapping: GestureMapping): void {
      var command: Object = _commandFactory.createCommand(mapping.command);
      var handler: Function = command[mapping.handlerMethod] as Function;
      
      this.executeCommand(command, handler, gesture);
    }
    
    protected function executeCommand(command: Object, handler: Function, gesture: Event): void {
      _commandExecutor.execute(command, handler, gesture);
    }
  }
}